package com.example.asus.drawstudy.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.example.asus.drawstudy.R;

/**
 * Created by liangkun on 2018/7/16.
 * 作用:
 */

public class WaterRipplesView extends View {
    Shader mBitmapShader = null;
    Bitmap mBitmapPn = null;
    Paint mPaint = null;
    Shader mRadialGradient = null;
    Canvas mCanvas = null;
    ShapeDrawable mShapeDrawable = null;

    public WaterRipplesView(Context context) {
        super(context);


    }

    public WaterRipplesView(Context context, AttributeSet attrs) {
        super(context, attrs);

        // 初始化工作
        Bitmap bitmapTemp = ((BitmapDrawable) getResources().getDrawable(
                R.drawable.leaf)).getBitmap();
        DisplayMetrics dm = getResources().getDisplayMetrics();
        // 创建与当前使用的设备窗口大小一致的图片
        mBitmapPn = Bitmap.createScaledBitmap(bitmapTemp, dm.widthPixels,
                dm.heightPixels, true);
        // 创建BitmapShader object
        mBitmapShader = new BitmapShader(mBitmapPn, Shader.TileMode.REPEAT,
                Shader.TileMode.MIRROR);
        mPaint = new Paint();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);

        // 将图片裁剪为椭圆型
        // 创建ShapeDrawable object，并定义形状为椭圆
        mShapeDrawable = new ShapeDrawable(new OvalShape());// OvalShape:椭圆
        // 设置要绘制的椭圆形的东西为ShapeDrawable图片
        mShapeDrawable.getPaint().setShader(mBitmapShader);
        // 设置显示区域
        mShapeDrawable.setBounds(0, 0, mBitmapPn.getWidth(),
                mBitmapPn.getHeight());
        // 绘制ShapeDrawable
        mShapeDrawable.draw(canvas);
        if (mRadialGradient != null) {
            mPaint.setShader(mRadialGradient);
            canvas.drawCircle(mBitmapPn.getWidth() / 2, mBitmapPn.getHeight() / 2, 1000, mPaint);
        }

    }

    // @覆写触摸屏事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // @设置alpha通道（透明度）
        mPaint.setAlpha(400);
        mRadialGradient = new RadialGradient(event.getX(), event.getY(), 48,
                new int[]{Color.WHITE, Color.TRANSPARENT}, null, Shader.TileMode.REPEAT);
        // @重绘
        postInvalidate();
        return true;
    }

    /**
     * 一般来说，自定义控件都会去重写View的onMeasure方法，因为该方法指定该控件在屏幕上的大小。
     * protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
     * onMeasure传入的两个参数是由上一层控件传入的大小，有多种情况，重写该方法时需要对计算控件的实际大小，然后调用setMeasure和尺寸组合在一起的数值。dDimension(int, int)设置实际大小。
     * onMeasure传入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸数值，而是将模式
     * 我们需要通过int mode = MeasureSpec.getMode(widthMeasureSpec)得到模式，用int size = MeasureSpec.getSize(widthMeasureSpec)得到尺寸。
     * mode共有三种情况，取值分别为MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。
     * MeasureSpec.EXACTLY是精确尺寸，当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width="50dip"，
     * 或者为FILL_PARENT是，都是控件大小已经确定的情况，都是精确尺寸。
     * MeasureSpec.AT_MOST是最大尺寸，当控件的layout_width或layout_height指定为WRAP_CONTENT时，
     * 控件大小一般随着控件的子空间或内容进行变化，此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此，此时的mode是AT_MOST，size给出了父控件允许的最大尺寸。
     * MeasureSpec.UNSPECIFIED是未指定尺寸，这种情况不多，一般都是父控件是AdapterView，通过measure方法传入的模式。
     * 因此，在重写onMeasure方法时要根据模式不同进行尺寸计算。下面代码就是一种比较典型的方式：
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measureWidth(widthMeasureSpec),
                measureHeight(heightMeasureSpec));
    }

    private int measureWidth(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        Log.i("DEMO", "measureSpec:" + Integer.toBinaryString(measureSpec));
        Log.i("DEMO", "specMode:" + Integer.toBinaryString(specMode));
        Log.i("DEMO", "specSize:" + Integer.toBinaryString(specSize));

//        if (specMode == MeasureSpec.EXACTLY) {
//            // We were told how big to be
//            result = specSize;
//        } else {
//            // Measure the text
//            result = (int) mTextPaint.measureText(mText) + getPaddingLeft()
//                    + getPaddingRight();
//            if (specMode == MeasureSpec.AT_MOST) {
//                // Respect AT_MOST value if that was what is called for by measureSpec
//                result = Math.min(result, specSize);
//            }
//        }
        return result;
    }

    private int measureHeight(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        Log.i("DEMO", "measureSpec:" + Integer.toBinaryString(measureSpec));
        Log.i("DEMO", "specMode:" + Integer.toBinaryString(specMode));
        Log.i("DEMO", "specSize:" + Integer.toBinaryString(specSize));

        return result;
    }
}
